﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KeywordAuction.Tactics
{
    public class BreadthFirstTactics : ITactics
    {
        public int Depth { get; set; }
     //   public List<string> AdvertiserIdList { get; set; }
        public Advertiser OwnerAdvertiser{ get; set; }
        public BreadthFirstTactics()
        {
            Depth = 1;
        }
        public IStrategy GetStrategy(Advertiser advertiser)
        {
            OwnerAdvertiser = advertiser;
            return ownerTactics(advertiser, advertiser.AttendingAuction); // ownerTactics(advertiser);
        }
        private IStrategy ownerTactics(Advertiser advertiser, AuctionHost host = null)
        {
            //AdvertiserIdList = advertiser.AttendingAuction.Advertisers.Where(p => p.Id != advertiser.Id).Select(p => p.Id).ToList();
            var simulationHosts = new List<SimulationAuctionHost>();
            simulationHosts.Add(host.Clone() as SimulationAuctionHost);
            
            for (int i = 0; i < Depth; i++)
            {
                var baseHosts = simulationHosts.ToList();
                simulationHosts.Clear();
                foreach (var itemHost in baseHosts)
                {
                    var baseHosts2 = new List<SimulationAuctionHost>();
                    foreach (var item in advertiser.Strategies)
                    {
                        simulationHosts.Clear();
                        var cloneHost = itemHost.Clone() as SimulationAuctionHost;
                        var cloneAdvertiser = cloneHost.Advertisers.Where(p => p.Id == advertiser.Id).FirstOrDefault();
                        if (item.Action(cloneAdvertiser))
                        {
                            cloneHost.ActorAdvertiser = cloneAdvertiser;
                            cloneAdvertiser.CurrentStrategy = item;
                            simulationHosts.Add(cloneHost);
                            var opponents = advertiser.AttendingAuction.Advertisers.Where(p => p.Id != advertiser.Id).ToList();
                            foreach (var opponent in opponents)
                            {
                                var cloneSimuHosts = simulationHosts.ToList();
                                simulationHosts.Clear();
                                foreach (var simuHost in cloneSimuHosts)
                                {
                                    foreach (var opponentStrategy in opponent.Strategies)
                                    {
                                        var cloneHost2 = simuHost.Clone() as SimulationAuctionHost;
                                        var cloneAdvertiser2 = cloneHost2.Advertisers.Where(p => p.Id == opponent.Id).FirstOrDefault();

                                        if (opponentStrategy.Action(cloneAdvertiser2))
                                        {
                                            cloneHost2.ActorAdvertiser = cloneAdvertiser2;
                                            simulationHosts.Add(cloneHost2);
                                        }
                                    }
                                }
                            }
                        }
                        baseHosts2.AddRange(simulationHosts);
                    }
                    simulationHosts = baseHosts2;
                }
            }
            var simulationList = simulationHosts.Select(p => new SimulationResult { Host = p, Value = 0 }).ToList();// new List<SimulationResult>();
            var checkHost = simulationHosts.First();
            for (int i = 0; i < host.Advertisers.Count * Depth ; i++)
            {
                string currentCheckingAdvertiserId = checkHost.ActorAdvertiser.Id;
                checkHost = checkHost.ParentAuctionHost;
                var parentCheckHost = simulationList.Select(p => p.Host).GroupBy(p => p.ParentAuctionHost).Select(p => p.Key).ToList();
                for (int i2 = 0; i2 < i; i2++)
                {
                   parentCheckHost= parentCheckHost.GroupBy(p => p.ParentAuctionHost).Select(p => p.Key).ToList();
                }
                //string currentCheckingAdvertiserId = OwnerAdvertiser.Id;

                //if (parentCheckHost.First().ActorAdvertiser != null)
                //{
                //    currentCheckingAdvertiserId = parentCheckHost.First().ActorAdvertiser.Id;
                //}
                

                var list  = simulationList.ToList();
                simulationList.Clear();
             
                var checkList = new List<SimulationAuctionHost>();
                foreach (var item in parentCheckHost)
                {
                    var groupedList = list.Where(p => IsGrouped(p.Host, i, item)).Select(p=>p.Host).ToList();
                  
                        double MaxValue = groupedList.Max(p => p.Advertisers.First(p2 => p2.Id == currentCheckingAdvertiserId).GetValue());
                        simulationList.AddRange(groupedList.Where(p => p.Advertisers.First(p2 => p2.Id == currentCheckingAdvertiserId).GetValue() == MaxValue).Select(p => new SimulationResult { Host = p, Value = MaxValue }));

                    //var currentAuctionResult = new List<SimulationResult>();
                    //foreach (var listCheck in )
                    //{
                        

                    //    var parentHost = listCheck.Host.ParentAuctionHost;
                    //    for (int i2 = 0; i2 < i; i2++)
                    //    {
                    //        parentHost = parentHost.ParentAuctionHost;
                    //    }
                    //    if (parentHost != item)
                    //    {
                    //        continue;
                    //    }

                    //    //double result = listCheck.Host.Advertisers.First(p => p.Id == currentCheckingAdvertiserId).GetValue();
                    //    //if (currentAuctionResult.Count == 0)
                    //    //{
                    //    //    currentAuctionResult.Add(new SimulationResult { Value = result, Host = listCheck.Host });
                    //    //}
                    //    //else if (result > currentAuctionResult[0].Value)
                    //    //{
                    //    //    currentAuctionResult.Clear();
                    //    //    currentAuctionResult.Add(new SimulationResult { Value = result, Host = listCheck.Host });
                    //    //}
                    //    //else if (result == currentAuctionResult[0].Value)
                    //    //{
                    //    //    currentAuctionResult.Add(new SimulationResult { Value = result, Host = listCheck.Host });
                    //    //}
                    //}
                    //simulationList.AddRange(currentAuctionResult.ToList());//.Select(p=>new SimulationResult {Host = p.Host.ParentAuctionHost}).ToList();
                }
            }
            var resultStrategy = simulationList.First().Host.Advertisers.First(p => p.Id == advertiser.Id).CurrentStrategy;
            return resultStrategy;
        }

        private bool IsGrouped(SimulationAuctionHost host, int depth, SimulationAuctionHost _parentHost)
        {
            var parentHost = host.ParentAuctionHost;
            for (int i = 0; i < depth; i++)
            {
                parentHost = parentHost.ParentAuctionHost;
            } 
            if (parentHost == _parentHost)
            {
                return true;
            }
            return false;
        }
    }
}
